package com.foreveross.util;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;

import com.foreveross.common.Exception.HttpClientException;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class HttpUtil {
	
	private static Logger log = Logger.getLogger(HttpUtil.class);
	
	/**
	 * 
	 * @param url
	 * @param params
	 * @return 这是post方式的同步方式 建议是用异步方式 {@AsynHttpUtil}
	 */
	public static String Post(String url, Map<String,String> params) {
		CloseableHttpClient client = HttpClientBuilder.create().build();
		String content = null;
		try {
			HttpPost httppost = new HttpPost(url);
			List <NameValuePair> nvps = new ArrayList <NameValuePair>();
			//提交两个参数及值
			for(Map.Entry<String, String> entry : params.entrySet()){
				nvps.add(new BasicNameValuePair(entry.getKey(),entry.getValue()));
			}
			//设置表单提交编码为UTF-8    requestEntity.setContentType("application/soap+xml; charset=utf-8");
			UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(nvps, HTTP.UTF_8);
			//urlEncodedFormEntity.setContentType("application/soap+xml; charset=utf-8");
			httppost.setEntity(urlEncodedFormEntity);
			
			HttpResponse response = client.execute(httppost);
		 
			HttpEntity entity = response.getEntity();
			content = EntityUtils.toString(entity);
			EntityUtils.consume(entity);
		} catch (Exception e) {
			HttpClientException.throwHttpClientException(e);
			log.error("同步访问"+url+"地址 POST请求出现异常!", e);   
		} finally {
			// client.getConnectionManager().shutdown();
			try {
				client.close();
			} catch (IOException e) {

				e.printStackTrace();
			}
		}

		return content;
	}
	
	
	/**
	 * 
	 * @param url
	 * @param params
	 * @return 这是post方式的同步方式 建议是用异步方式 {@AsynHttpUtil}
	 */
	public static String Post(String url, Map<String,String> header, Map<String,String> params) {
		CloseableHttpClient client = HttpClientBuilder.create().build();
		String content = null;
		try {
			HttpPost httppost = new HttpPost(url);
			//设置Header
			for(Map.Entry<String, String> entry : header.entrySet()){
				httppost.addHeader(entry.getKey(),entry.getValue());
			}
			
			// 设置请求的参数
			List <NameValuePair> nvps = new ArrayList <NameValuePair>();
			for(Map.Entry<String, String> entry : params.entrySet()){
				nvps.add(new BasicNameValuePair(entry.getKey(),entry.getValue()));
			}
			UrlEncodedFormEntity urlEncodedFormEntity = new UrlEncodedFormEntity(nvps, "utf-8");
			httppost.setEntity(urlEncodedFormEntity);
			
			HttpResponse response = client.execute(httppost);
		 
			HttpEntity entity = response.getEntity();
			content = EntityUtils.toString(entity);
			EntityUtils.consume(entity);
		} catch (Exception e) {
			HttpClientException.throwHttpClientException(e);
			log.error("同步访问"+url+"地址 POST请求出现异常!", e);   
		} finally {
			// client.getConnectionManager().shutdown();
		}

		return content;
	}
	
	
	 
	
	public static String PostByJson(String url, String jsonParams) {
		CloseableHttpClient client = HttpClientBuilder.create().build();
		String content = null;
		try {
			HttpPost httppost = new HttpPost(url);
			 // 将JSON进行UTF-8编码,以便传输中文
			//设置表单提交编码为UTF-8
			StringEntity stringEntity = new StringEntity(jsonParams,"UTF-8");
			stringEntity.setContentType("application/json");
			stringEntity.setContentEncoding("UTF-8");
			httppost.setEntity(stringEntity);
			HttpResponse response = client.execute(httppost);
			HttpEntity entity = response.getEntity();
			content = EntityUtils.toString(entity);
			EntityUtils.consume(entity);
		} catch (Exception e) {
			HttpClientException.throwHttpClientException(e);
			log.error("同步访问"+url+"地址 POST请求出现异常!", e);   
		} finally {
			// client.getConnectionManager().shutdown();
			try {
				client.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		return content;
	}
	
	public static String PostBySoap(String url, String soapRequestData) {
		CloseableHttpClient client = HttpClientBuilder.create().build();
		String content = null;
		try {
			HttpPost httppost = new HttpPost(url);
			 // 将JSON进行UTF-8编码,以便传输中文
			//设置表单提交编码为UTF-8
			byte[] bytes = soapRequestData.getBytes("utf-8");
			
	        InputStream inputStream = new ByteArrayInputStream(bytes, 0,
	                bytes.length);
	        InputStreamEntity requestEntity = new InputStreamEntity(inputStream);
	     requestEntity.setContentType("application/soap+xml; charset=utf-8");
	        
			httppost.setEntity(requestEntity);
			HttpResponse response = client.execute(httppost);
			HttpEntity entity = response.getEntity();
			content = EntityUtils.toString(entity);
			EntityUtils.consume(entity);
		} catch (Exception e) {
			HttpClientException.throwHttpClientException(e);
			e.printStackTrace();
			log.error("同步访问"+url+"地址 POST请求出现异常!", e);   
		} finally {
			// client.getConnectionManager().shutdown();
			try {
				client.close();
			} catch (IOException e) {

				e.printStackTrace();
			}
		}

		return content;
	}

	/**
	 * 
	 * @param url
	 * @param params
	 * @return 这是get方式的同步方式 建议是用异步方式 {@AsynHttpUtil}
	 */
	public static String get(String url, Map params) {
		CloseableHttpClient client = HttpClientBuilder.create().build();
		String content = null;
		try {
			HttpGet get = new HttpGet(url + "?" + stringify(params));
			HttpResponse response = client.execute(get);
			HttpEntity entity = response.getEntity();
			content = EntityUtils.toString(entity);
			EntityUtils.consume(entity);
		} catch (Exception e) {
			HttpClientException.throwHttpClientException(e);
		} finally {
			// client.getConnectionManager().shutdown();
			try {
				client.close();
			} catch (IOException e) {

				e.printStackTrace();
			}
		}

		return content;
	}

	public static String get(String url) {
		CloseableHttpClient client = HttpClientBuilder.create().build();
		// new DefaultHttpClient();
		String content = null;
		try {
			HttpGet get = new HttpGet(url);
			HttpResponse response = client.execute(get);
			HttpEntity entity = response.getEntity();
			content = EntityUtils.toString(entity);
			EntityUtils.consume(entity);
		} catch (Exception e) {
			HttpClientException.throwHttpClientException(e);
		} finally {
			// client.getConnectionManager().shutdown(); //4.3 被遗弃掉了
			try {
				client.close();
			} catch (IOException e) {

				e.printStackTrace();
			}
		}

		return content;
	}

	public static String stringify(Map<String, Object> map) {
		if (map == null)
			return null;
		StringBuilder builder = new StringBuilder();
		for (Map.Entry<String, Object> entry : map.entrySet()) {
			builder.append(entry.getKey()).append("=").append(entry.getValue())
					.append("&");
		}

		return builder.deleteCharAt(builder.length() - 1).toString();
	}

	public static void sendHttp(final String tokenUrl,
			final List<Map<String, Object>> paramsList) {
		int thread_num = 100;
		ExecutorService exec = Executors.newCachedThreadPool();
		// 100个线程可以同时访问
		final Semaphore semp = new Semaphore(thread_num);
		long ftime = System.currentTimeMillis();
		for (int index = 0; index < paramsList.size(); index++) {

			final int NO = index;

			Runnable run = new Runnable() {
				public void run() {
					try {
						// 获取许可

						semp.acquire();
						// System.out.println( "Thread:" + NO );
						String json = HttpUtil.Post(tokenUrl,(Map)paramsList.get(NO));
						// System.out.println("json is "+json);

						// 释放
						Thread.sleep(2000);
						semp.release();

					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			};

			exec.execute(run);

		}

		// 退出线程池
		long etime = System.currentTimeMillis();
		log.info("HttpUtil同步方式执行100个并发访问"+paramsList.size()+"个服务端所花费的时间 "+(etime-ftime)+"毫秒");
		exec.shutdown();
	}

	public static void main(String[] args) {
		String tokenUrl = "http://szsya.gicp.net:9090/NetApp/SYS86Service.asmx";
		Map paramsList = new HashMap();
		paramsList.put("strToken", "syswin");
		paramsList.put("p0", "UserRev_OwnerVerify");
		paramsList.put("p1", "尹秀容");
		paramsList.put("p2", "13800010001");
		String str = Post(tokenUrl, paramsList);
		System.out.println(str);
		
		/*int thread_num = 50;

		int client_num = 2000;
		final String tokenUrl = "https://openapi.baidu.com/social/oauth/2.0/token";

		ExecutorService exec = Executors.newCachedThreadPool();
		// 50个线程可以同时访问
		final Semaphore semp = new Semaphore(thread_num);
		// 模拟460个客户端访问
		long ftime = System.currentTimeMillis();
		for (int index = 0; index < client_num; index++) {

			final int NO = index;

			Runnable run = new Runnable() {
				public void run() {
					try {
						// 获取许可

						semp.acquire();
						// System.out.println( "Thread:" + NO );
						String json = HttpUtil.get(tokenUrl);
						// System.out.println("json is "+json);

						// 释放
						Thread.sleep(2000);
						semp.release();

					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			};

			exec.execute(run);

		}

		// 退出线程池
		long etime = System.currentTimeMillis();
		System.out.println("httpUtil同步方式执行50个并发访问 2000个客服端所花费的时间 "
				+ (etime - ftime) + " s");
		exec.shutdown();*/
	}
}
